import React, { useState, useEffect } from 'react';

const UseEffectDemo: React.FC = () => {
  const [count, setCount] = useState<number>(0);
  const [userId, setUserId] = useState<number>(1);
  const [userData, setUserData] = useState<any>(null);
  const [loading, setLoading] = useState<boolean>(false);
  const [windowWidth, setWindowWidth] = useState<number>(window.innerWidth);
  const [isVisible, setIsVisible] = useState<boolean>(true);

  // 1. 基本用法 - 每次渲染后都执行
  useEffect(() => {
    console.log('组件渲染完成，count值为:', count);
  });

  // 2. 只在挂载时执行一次
  useEffect(() => {
    console.log('组件首次挂载完成');
    return () => {
      console.log('组件即将卸载');
    };
  }, []);

  // 3. 依赖数组 - 只在count变化时执行
  useEffect(() => {
    console.log('count发生变化:', count);
    document.title = `计数器: ${count}`;
  }, [count]);

  // 4. 清理函数 - 移除事件监听器
  useEffect(() => {
    const handleResize = () => {
      setWindowWidth(window.innerWidth);
    };

    window.addEventListener('resize', handleResize);
    
    return () => {
      window.removeEventListener('resize', handleResize);
    };
  }, []);

  // 5. 数据获取
  useEffect(() => {
    const fetchUserData = async () => {
      setLoading(true);
      try {
        const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
        const data = await response.json();
        setUserData(data);
      } catch (error) {
        console.error('获取用户数据失败:', error);
      } finally {
        setLoading(false);
      }
    };

    fetchUserData();
  }, [userId]);

  // 6. 定时器清理
  useEffect(() => {
    if (!isVisible) return;

    const timer = setInterval(() => {
      setCount(prev => prev + 1);
    }, 1000);

    return () => {
      clearInterval(timer);
    };
  }, [isVisible]);

  return (
    <div className="demo-page">
      <h1>useEffect Hook 演示</h1>
      <p className="description">
        useEffect用于处理副作用，如数据获取、订阅、手动更改DOM等。
      </p>

      {/* 计数器示例 */}
      <section className="demo-section">
        <h2>1. 基本计数器（自动递增）</h2>
        <div className="counter-demo">
          <p>当前计数: {count}</p>
          <div className="button-group">
            <button onClick={() => setCount(count + 1)}>手动增加</button>
            <button onClick={() => setCount(0)}>重置</button>
            <button onClick={() => setIsVisible(!isVisible)}>
              {isVisible ? '暂停' : '继续'}自动递增
            </button>
          </div>
          <p className="note">注意：查看浏览器标题栏的变化</p>
        </div>
      </section>

      {/* 窗口大小监听 */}
      <section className="demo-section">
        <h2>2. 窗口大小监听</h2>
        <div className="window-size-demo">
          <p>当前窗口宽度: <strong>{windowWidth}px</strong></p>
          <p className="note">尝试调整浏览器窗口大小</p>
        </div>
      </section>

      {/* 数据获取示例 */}
      <section className="demo-section">
        <h2>3. 数据获取与依赖管理</h2>
        <div className="data-fetch-demo">
          <div className="user-selector">
            <label>选择用户ID: </label>
            <select 
              value={userId} 
              onChange={(e) => setUserId(Number(e.target.value))}
            >
              {[1, 2, 3, 4, 5].map(id => (
                <option key={id} value={id}>用户 {id}</option>
              ))}
            </select>
          </div>

          {loading && <div className="loading">加载中...</div>}
          
          {userData && (
            <div className="user-info">
              <h3>用户信息</h3>
              <p><strong>姓名:</strong> {userData.name}</p>
              <p><strong>用户名:</strong> {userData.username}</p>
              <p><strong>邮箱:</strong> {userData.email}</p>
              <p><strong>地址:</strong> {userData.address?.city}</p>
              <p><strong>公司:</strong> {userData.company?.name}</p>
            </div>
          )}
        </div>
      </section>

      {/* 使用要点 */}
      <section className="demo-section">
        <h2>4. 使用要点与最佳实践</h2>
        <div className="best-practices">
          <div className="practice-item">
            <h3>依赖数组的使用</h3>
            <ul>
              <li><code>[]</code> - 只在组件挂载时执行一次</li>
              <li><code>[dep1, dep2]</code> - 在指定依赖变化时执行</li>
              <li>无依赖数组 - 每次渲染后都执行</li>
            </ul>
          </div>

          <div className="practice-item">
            <h3>清理函数</h3>
            <ul>
              <li>用于清理订阅、定时器、事件监听器</li>
              <li>在组件卸载或依赖变化前执行</li>
              <li>防止内存泄漏</li>
            </ul>
          </div>

          <div className="practice-item">
            <h3>异步操作</h3>
            <ul>
              <li>在useEffect中处理异步操作</li>
              <li>使用取消标记避免竞态条件</li>
              <li>正确处理加载和错误状态</li>
            </ul>
          </div>
        </div>
      </section>

      {/* 代码示例 */}
      <section className="demo-section">
        <h2>5. 代码示例</h2>
        <div className="code-example">
          <h3>基本语法:</h3>
          <pre>
{`// 基本用法
useEffect(() => {
  // 副作用逻辑
  console.log('Effect executed');
  
  return () => {
    // 清理逻辑（可选）
    console.log('Cleanup');
  };
}, [dependency]); // 依赖数组（可选）`}
          </pre>

          <h3>数据获取示例:</h3>
          <pre>
{`useEffect(() => {
  let isCancelled = false;
  
  const fetchData = async () => {
    try {
      const response = await fetch(url);
      const data = await response.json();
      if (!isCancelled) {
        setData(data);
      }
    } catch (error) {
      if (!isCancelled) {
        setError(error);
      }
    }
  };
  
  fetchData();
  
  return () => {
    isCancelled = true;
  };
}, [url]);`}
          </pre>
        </div>
      </section>
    </div>
  );
};

export default UseEffectDemo;